#pragma once

#include <linux/bitops.h>

enum pageflags
{
    PG_head,
};

/*
 * For pages that do not use mapcount, page_type may be used.
 * The low 24 bits of pagetype may be used for your own purposes, as long
 * as you are careful to not affect the top 8 bits.  The low bits of
 * pagetype will be overwritten when you clear the page_type from the page.
 */
enum pagetype
{
    /* 0x00-0x7f are positive numbers, ie mapcount */
    /* Reserve 0x80-0xef for mapcount overflow. */
    PGTY_buddy = 0xf0,
    PGTY_offline = 0xf1,
    PGTY_table = 0xf2,
    PGTY_guard = 0xf3,
    PGTY_hugetlb = 0xf4,
    PGTY_slab = 0xf5,
    PGTY_zsmalloc = 0xf6,
    PGTY_unaccepted = 0xf7,
    PGTY_large_kmalloc = 0xf8,

    PGTY_mapcount_underflow = 0xff
};

static inline const struct page *page_fixed_fake_head(const struct page *page)
{
	return page;
}

static inline int page_is_fake_head(const struct page *page)
{
	return page_fixed_fake_head(page) != page;
}

static inline int PageHead(const struct page *page)
{
	return test_bit(PG_head, &page->flags) && !page_is_fake_head(page);
}

static inline int PageBuddy(const struct page *page)		\
{									\
    return (page->page_type >> 24) == PGTY_buddy;	\
}

static inline void __PageTypeSet(struct page *page, enum pagetype t)
{
    page->page_type = (unsigned int)t << 24;
}

static inline void __PageTypeClear(struct page *page)
{
    page->page_type = 0xffffffff;
}

#define __SetPageBuddy(page) __PageTypeSet(page, PGTY_buddy)
#define __ClearPageBuddy(page) __PageTypeClear(page)
